<!-- 文档分类: IMPL-RPT-018 | 阶段: 实现 | 原路径: docs/指南/管理前端自动可用修复-2026-05-31.md -->
管理前端自动可用修复#
日期: 2026-05-31 | 影响:
khy gateway manage
问题#
khy gateway manage 启动管理界面时,前端始终显示 "未就绪(pip 安装暂不含预构建前端)",
即使 ai-frontend/dist/ 已有完整构建产物。
前端: 未就绪
前端原因: unavailable
推荐入口: API 直管(当前无可用前端)
根因分析#
三处断裂导致前端不可用:
断裂 1: setup.py 不打包 ai-frontend/#
BuildWithBundle.run() 只复制 frontend/dist/(旧路径,已不存在),
从未打包 ai-frontend/ 源码或预构建产物。pip 安装后目标机器上没有前端文件。
断裂 2: _bootstrap.py 不装 ai-frontend 依赖#
runtime npm install 只针对 backend/,从未对 ai-frontend/ 执行。
即使前端源码存在,缺少 node_modules 导致 Vite dev server 无法启动。
断裂 3: daemon 不回退到静态 dist#
ai-manage-daemon.js 存在以下问题:
- 不解析
--frontend-dist-dir参数(spawner 传了但 daemon 忽略了) - 不调用
aiManagementServer.configureFrontendStatic()(函数已导出但从未被使用)
当 node_modules 缺失时,noAutoFrontend 自动设为 true,resolveFrontend() 跳过 Vite dev server,外部端口探测也失败,结果 frontendAvailable = false。
修复#
1. setup.py — 打包 ai-frontend/#
在 BuildWithBundle.run() 中添加 ai-frontend/ copytree:
ai_frontend_src = ROOT / "ai-frontend"
ai_frontend_dst = bundled / "ai-frontend"
if ai_frontend_src.exists():
shutil.copytree(
ai_frontend_src, ai_frontend_dst,
ignore=shutil.ignore_patterns(*EXCLUDE_PATTERNS, 'node_modules'),
)
MANIFEST.in 同步添加 recursive-include ai-frontend * + prune ai-frontend/node_modules。
2. _bootstrap.py — ai-frontend npm install#
在 _ensure_npm_install() 的 finally 块中添加 ai-frontend 依赖安装:
ai_frontend_dir = backend_dir.parent / "ai-frontend"
if ai_frontend_dir.exists() and (ai_frontend_dir / "package.json").exists():
nm = ai_frontend_dir / "node_modules"
lock = nm / ".package-lock.json"
if not _path_exists_safe(nm) or not _path_exists_safe(lock):
subprocess.run(
[npm_cmd, "install", "--no-audit", "--no-fund"],
cwd=str(ai_frontend_dir), timeout=_NPM_TIMEOUT,
**_subprocess_kwargs(),
)
3. ai-manage-daemon.js — 解析参数 + 静态回退#
解析 --frontend-dist-dir 参数:
const frontendDistDir = parseStringArg(argv, '--frontend-dist-dir', '');
resolveFrontend() 失败后回退到静态托管:
if (!frontend.available && frontendDistDir) {
const staticResult = aiManagementServer.configureFrontendStatic({
distDir: frontendDistDir,
});
if (staticResult.enabled) {
frontend.available = true;
frontend.managed = true;
frontend.port = apiPort; // 静态文件从 API 端口提供
frontend.reason = 'static-dist';
}
}
4. gateway.js — 修正提示信息#
移除硬编码的 "pip 安装暂不含预构建前端" 文案,改为通用 "管理前端未就绪"。
修复后行为#
| 场景 | 前端来源 | 端口 |
|---|---|---|
有 node_modules | Vite dev server | 8090 |
无 node_modules,有 dist/ | configureFrontendStatic() 静态托管 | 9090 (API 同端口) |
| pip 安装首次启动 | runtime npm install 后 Vite dev server | 8090 |
完整链路:
pip install → 打包 ai-frontend/ (源码 + dist/)
→ runtime _bootstrap.py → cd ai-frontend && npm install
→ khy gateway manage → daemon → 优先 Vite dev server (8090)
→ 回退 configureFrontendStatic (9090/admin/ai-gateway)
→ 前端可用
修改文件#
| 文件 | 改动 |
|---|---|
setup.py | BuildWithBundle.run() 添加 ai-frontend copytree |
MANIFEST.in | 添加 ai-frontend include + prune node_modules |
khy_platform/_bootstrap.py | _ensure_npm_install() finally 块安装 ai-frontend 依赖 |
backend/scripts/ai-manage-daemon.js | 解析 --frontend-dist-dir + 静态回退 |
backend/src/cli/handlers/gateway.js | 修正 "未就绪" 提示信息 |
验证#
# 正常模式(有 node_modules)
khy gateway manage
# → 前端: http://127.0.0.1:8090
# 模拟 pip 场景(无 node_modules)
mv ai-frontend/node_modules ai-frontend/_bak
khy gateway manage stop && khy gateway manage start --daemon
# → 前端: http://127.0.0.1:9090 (静态 dist 回退)
curl -s http://127.0.0.1:9090/admin/ai-gateway | head -1
# → <!DOCTYPE html>
# 恢复
khy gateway manage stop
mv ai-frontend/_bak ai-frontend/node_modules